package org.gensokyo.crawler.luoli

import java.util.UUID

import com.gargoylesoftware.htmlunit._
import com.gargoylesoftware.htmlunit.html._
import com.typesafe.scalalogging.slf4j.StrictLogging
import org.apache.commons.codec.digest.DigestUtils
import org.gensokyo.crawler.proxy.ProxyInfo
import org.json4s.jackson.Serialization._

import scala.collection.Map
import scala.collection.parallel.ForkJoinTaskSupport

object LuoliziyuanHandler extends StrictLogging {

  import scalaj.collection.Imports._

  implicit val formats = org.json4s.DefaultFormats

  def handle(proxyIp: String, proxyPort: Int) = {
    logger.debug(s"""proxyIp=${proxyIp},proxyPort=${proxyPort}""")
    val username = DigestUtils.md5Hex(UUID.randomUUID().toString).substring(0, (math.round(math.random * 3.0) + 10).toInt)
    val email = s"""${username}@${getEmailTail}"""
    logger.debug(s"username:${username} email:${email}")
    var page: HtmlPage = null
    var webClient: WebClient = null
    try {
      logger.debug("start")
      webClient = new WebClient(BrowserVersion.FIREFOX_45, proxyIp, proxyPort)
      webClient.getOptions.setTimeout(30 * 1000)
      webClient.getOptions.setThrowExceptionOnScriptError(false)
      webClient.getOptions.setThrowExceptionOnFailingStatusCode(false)
      webClient.setConfirmHandler(new ConfirmHandler() {
        def handleConfirm(page: Page, message: String): Boolean = {
          logger.debug(s"----------------------------------------")
          logger.debug(s"confirm message:${message}")
          logger.debug(s"----------------------------------------")
          true
        }
      })
      webClient.setAlertHandler(new AlertHandler() {
        override def handleAlert(page: Page, message: String): Unit = {
          logger.debug(s"----------------------------------------")
          logger.debug(s"alert message:${message}")
          logger.debug(s"----------------------------------------")
        }
      })
      //      webClient.getOptions.setJavaScriptEnabled(false)
      //      webClient.setJavaScriptTimeout(10L)

      val url1 = "http://www.luoliziyuan.net/?fromuser=happy906381"
      val page1: HtmlPage = webClient.getPage(url1)
      if (page1.querySelector("#ERR_ACCESS_DENIED") != null) {
        throw new Exception("Squid proxy error!")
      }

      logger.debug(s"cookies:${webClient.getCookieManager.getCookies.asScalaMutable.toList}")
      val page2: HtmlPage = webClient.getPage("http://www.luoliziyuan.net/member.php?mod=register")
      page2.querySelector("""#layer_reg input#g3nRQx""").asInstanceOf[HtmlTextInput].setValueAttribute(username)
      page2.querySelector("""#layer_reg input#VNdv53""").asInstanceOf[HtmlPasswordInput].setValueAttribute(username)
      page2.querySelector("""#layer_reg input#ChW48n""").asInstanceOf[HtmlPasswordInput].setValueAttribute(username)
      page2.querySelector("""#layer_reg input#t1In4g""").asInstanceOf[HtmlTextInput].setValueAttribute(email)
      Thread.sleep(3000L)
      //      scala.tools.nsc.io.File("page1.html").writeAll(page2.asXml())
      logger.debug(s"page.asText()=${stripSpace(page2.asText())}")
      val page3: HtmlPage = page2.querySelector("""#registerformsubmit""").asInstanceOf[HtmlButton].click()
      //      scala.tools.nsc.io.File("page2.html").writeAll(page2.asXml())
      logger.debug(s"page.asText()=${stripSpace(page3.asText())}")
      Thread.sleep(5000L)
      logger.debug(s"page.asText()=${stripSpace(page3.asText())}")
      if (stripSpace(page3.asText()).contains("如果您的浏览器没有自动跳转，请点击此链接")) {
        logger.debug("success")
        writeResultFile(s"${proxyIp} ${proxyPort} ${username} ${email}")
      } else {
        logger.debug("error")
      }
      //      scala.tools.nsc.io.File("page3.html").writeAll(page3.asXml())
      logger.debug("deal over")
      Thread.sleep(3000L)
    } catch {
      case e: Exception => {
        writeResultFile(s"${proxyIp} ${proxyPort}")
        logger.error(e.getMessage)
      }
    } finally {
      webClient.close()
    }
  }

  def deal = {
    val proxyInfo = read[List[ProxyInfo]](scala.io.Source.fromFile("proxy.json").getLines().filter(_.length > 0).mkString("\n"))
    val result: List[(String, String)] = scala.io.Source.fromFile("result.txt").getLines().toList.map(x => {
      val l = x.split(" ").toList
      (l.apply(0), l.apply(1))
    })
    val parProxyInfo = proxyInfo.filter(x => !result.contains((x.ip, x.port))).par
    parProxyInfo.tasksupport = new ForkJoinTaskSupport(new scala.concurrent.forkjoin.ForkJoinPool(30))
    parProxyInfo.foreach(x => handle(x.ip, x.port.toInt))
  }

  def writeResultFile(str: String) = synchronized {
    scala.tools.nsc.io.File("result.txt").appendAll(s"\n${str}")
  }


  def main(args: Array[String]): Unit = {
    deal
  }

}
